package com.hsgene.user.controller.organization;

import com.hsgene.common.exception.CommonErrorCode;
import com.hsgene.common.util.basic.SimpleStringUtils;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.common.util.support.LimitHelper;
import com.hsgene.common.util.support.OrderHelper;
import com.hsgene.common.util.support.Pagination;
import com.hsgene.user.condition.DepartmentCondition;
import com.hsgene.user.domain.Department;
import com.hsgene.user.dto.orginazation.DepartmentDto;
import com.hsgene.user.dto.orginazation.DepartmentIdsDto;
import com.hsgene.user.exception.OrganizationErrorCode;
import com.hsgene.user.service.CompanyService;
import com.hsgene.user.service.DepartmentService;
import com.hsgene.user.service.PositionService;
import com.hsgene.user.service.api.AuthService;
import com.hsgene.user.service.api.GeneratorService;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @description: 部门管理类
 * @projectName: hdas-geneshop-server
 * @package: com.hsgene.order.controller.organization
 * @author: maodi
 * @createDate: 2018/11/5 10:03
 * @version: 1.0
 * Copyright: Copyright (c) 2018
 */
@RestController
@RequestMapping("/v1.0/genetic/testing/departments")
public class DepartmentController {

    private static Logger LOGGER = LogManager.getLogger(DepartmentController.class);

    @Resource
    DepartmentService departmentService;

    @Resource
    PositionService positionService;

    @Resource
    GeneratorService generatorService;

    @Resource
    CompanyService companyService;

    @Resource
    AuthService authService;

    /**
     * @param departmentName 部门名称
     * @param companyId      公司id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 部门插入去重
     * @author maodi
     * @createDate 2018/11/13 17:34
     */
    @GetMapping("insert/repeat")
    public ApiResult<NullObject> insertRepeat(@RequestParam("departmentName") String departmentName, @RequestParam
            ("companyId") String companyId) {
        try {
            if (StringUtils.isBlank(departmentName)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int count = departmentService.queryDepartmentCountByName(departmentName, companyId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_EXIST);
            }
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.INSERT_DEPARTMENT_REPEAT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.INSERT_DEPARTMENT_REPEAT_IS_ERROR);
        }
    }

    /**
     * @param departmentName 部门名称
     * @param companyId      公司id
     * @param departmentId   部门id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 修改去重
     * @author maodi
     * @createDate 2018/11/13 17:39
     */
    @GetMapping("update/repeat")
    public ApiResult<NullObject> updateRepeat(@RequestParam("departmentName") String departmentName, @RequestParam
            ("companyId") String companyId, @RequestParam("departmentId") String departmentId) {
        try {
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(departmentName)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_NOT_NULL);
            }
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int count = departmentService.queryDepartmentCountByNameExcludeSelf(departmentName, companyId,
                    departmentId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_EXIST);
            }
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.UPDATE_DEPARTMENT_REPEAT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.UPDATE_DEPARTMENT_REPEAT_IS_ERROR);
        }
    }

    /**
     * @param departmentId 部门id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.user.domain.Department>
     * @description 根据部门id获取部门信息
     * @author maodi
     * @createDate 2018/11/13 17:46
     */
    @GetMapping("{department_id}")
    public ApiResult<Department> getDepartmentByDepartmentId(@PathVariable("department_id") String departmentId) {
        try {
            List<DepartmentDto> list = departmentService.queryDepartmentById(departmentId);
            if (list != null && list.size() > 0) {
                return ApiResult.succ(list.get(0));
            } else {
                return ApiResult.succ(null, "暂无数据");
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.QUERY_DEPARTMENT_BY_ID_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.QUERY_DEPARTMENT_BY_ID_IS_ERROR);
        }
    }

    /**
     * @param companyId 公司id
     * @return com.hsgene.common.util.result.ApiResult<java.util.List<java.util.Map<java.lang.String,java.lang.Object>>>
     * @description 根据公司id查询部门下拉框数据源
     * @author maodi
     * @createDate 2018/11/7 9:25
     */
    @GetMapping("select/{company_id}")
    public ApiResult<List<Map<String, Object>>> select(@PathVariable("company_id") String companyId) {
        try {
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            return ApiResult.succ(departmentService.selectDepartment(companyId));
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.SELECT_DEPARTMENT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.SELECT_DEPARTMENT_IS_ERROR);
        }
    }

    /**
     * @param page           页数
     * @param size           每页数量
     * @param departmentName 部门名称
     * @param companyName    公司名称
     * @param sort           修改时间排序规则
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.support.Pagination<com.hsgene.user.dto
     * .orginazation.DepartmentDto>>
     * @description 查询部门信息/部门列表
     * @author maodi
     * @createDate 2018/11/7 9:03
     */
    @GetMapping
    public ApiResult<Pagination<DepartmentDto>> queryDepartment(
            @RequestParam("page") Integer page,
            @RequestParam("size") Integer size,
            @RequestParam(name = "departmentName", required = false) String departmentName,
            @RequestParam(name = "companyName", required = false) String companyName,
            @RequestParam(name = "sort", required = false, defaultValue = "desc") String sort) {
        try {
            if (page == null) {
                return ApiResult.fail(CommonErrorCode.PAGE_IS_NULL);
            }
            if (!SimpleStringUtils.isPositiveInteger(page.toString())) {
                return ApiResult.fail(CommonErrorCode.PAGE_IS_NOT_POSITIVE_INTEGER);
            }
            if (size == null) {
                return ApiResult.fail(CommonErrorCode.SIZE_IS_NULL);
            }
            if (!SimpleStringUtils.isPositiveInteger(size.toString())) {
                return ApiResult.fail(CommonErrorCode.SIZE_IS_NOT_POSITIVE_INTEGER);
            }
            sort = sort.toLowerCase();
            if (!"desc".equalsIgnoreCase(sort) && !"asc".equalsIgnoreCase(sort)) {
                return ApiResult.fail(CommonErrorCode.SORT_ORDER_IS_ERROR);
            }
            DepartmentCondition condition = new DepartmentCondition();
            condition.setCompanyName(companyName);
            condition.setDepartmentName(departmentName);
            LimitHelper limitHelper = LimitHelper.create(page, size, false);
            condition.setLimitHelper(limitHelper);
            OrderHelper orderHelper = OrderHelper.create("gtod.update_date_time", sort);
            condition.setOrderHelper(orderHelper);
            List<DepartmentDto> result = departmentService.queryDepartmentByCondition(condition);
            addNum(result, page, size);
            int totalCount = departmentService.queryDepartmentCountByCondition(condition);
            Pagination pagination = Pagination.newInstance(limitHelper, totalCount, result);
            return ApiResult.succ(pagination);
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.QUERY_DEPARTMENT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.QUERY_DEPARTMENT_IS_ERROR);
        }
    }

    /**
     * @param department 部门信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 新增部门信息
     * @author maodi
     * @createDate 2018/11/7 9:27
     */
    @PostMapping
    public ApiResult<NullObject> insertDepartment(@RequestBody Department department) {
        try {
            String departmentName = department.getDepartmentName();
            if (StringUtils.isBlank(departmentName)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_NOT_NULL);
            }
            String companyId = department.getCompanyId();
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            int count = departmentService.queryDepartmentCountByName(departmentName, companyId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_EXIST);
            }
            String id = generatorService.getGenerator("", "").getData().getSerialNumber();
            department.setId(id);
            Date date = new Date();
            department.setCreateDateTime(date);
            department.setUpdateDateTime(date);
            departmentService.insertDepartment(department);
            ApiResult<NullObject> result = authService.initDepartmentPermission(department.getId(), "init");
            if (!result.isSucc()) {
                throw new RuntimeException(result.getMessage());
            }
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.INSERT_DEPARTMENT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.INSERT_DEPARTMENT_IS_ERROR);
        }
    }

    /**
     * @param departmentId 部门id
     * @param department   部门信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 修改部门信息
     * @author maodi
     * @createDate 2018/11/7 9:51
     */
    @PutMapping("{department_id}")
    public ApiResult<NullObject> updateDepartment(@PathVariable("department_id") String departmentId, @RequestBody
            Department department) {
        try {
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            department.setId(departmentId);
            String departmentName = department.getDepartmentName();
            if (StringUtils.isBlank(departmentName)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_NOT_NULL);
            }
            String companyId = department.getCompanyId();
            if (StringUtils.isBlank(companyId)) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_NULL);
            }
            int existCompanyCount = companyService.queryCompanyById(companyId).size();
            if (existCompanyCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.COMPANY_ID_IS_NOT_EXIST);
            }
            List<DepartmentDto> departmentList = departmentService.queryDepartmentById(departmentId);
            String oldCompanyId = null;
            if (departmentList != null && departmentList.size() > 0) {
                oldCompanyId = departmentList.get(0).getCompanyId();
            }
            if (oldCompanyId == null || !companyId.equals(oldCompanyId)) {
                return ApiResult.fail(OrganizationErrorCode.CAN_NOT_UPDATE_COMPANY);
            }
            int count = departmentService.queryDepartmentCountByNameExcludeSelf(departmentName, companyId,
                    departmentId);
            if (count > 0) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_NAME_IS_EXIST);
            }
            int queryCount = departmentService.queryDepartmentById(departmentId).size();
            if (queryCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_IS_NOT_EXIST);
            }
            department.setId(departmentId);
            department.setUpdateDateTime(new Date());
            int returnCount = departmentService.updateDepartment(department);
            if (returnCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.UPDATE_DEPARTMENT_IS_ERROR);
            } else if (returnCount > 1) {
                return ApiResult.succ(null, OrganizationErrorCode.DEPARTMENT_IS_MULTI.getDescription());
            } else {
                return ApiResult.succ();
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.UPDATE_DEPARTMENT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.UPDATE_DEPARTMENT_IS_ERROR);
        }
    }

    /**
     * @param departmentId 部门id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 删除部门信息
     * @author maodi
     * @createDate 2018/11/7 9:58
     */
    @DeleteMapping("{department_id}")
    public ApiResult<NullObject> deleteDepartment(@PathVariable("department_id") String departmentId) {
        try {
            if (StringUtils.isBlank(departmentId)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_ID_IS_NOT_NULL);
            }
            int queryCount = departmentService.queryDepartmentById(departmentId).size();
            if (queryCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_HAVE_BEEN_DELETED);
            }
            int usedCount = positionService.queryCountByDepartmentId(departmentId);
            if (usedCount > 0) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_IS_USED_CAN_NOT_DELETE);
            }
            Department department = new Department();
            department.setId(departmentId);
            department.setUpdateDateTime(new Date());
            int returnCount = departmentService.deleteDepartment(department);
            if (returnCount < 1) {
                return ApiResult.fail(OrganizationErrorCode.DELETE_DEPARTMENT_IS_ERROR);
            } else {
                ApiResult<NullObject> result = authService.initDepartmentPermission(department.getId(), "clear");
                if (!result.isSucc()) {
                    throw new RuntimeException(result.getMessage());
                }
                if (returnCount > 1) {
                    return ApiResult.succ(null, OrganizationErrorCode.DEPARTMENT_IS_MULTI.getDescription());
                } else {
                    return ApiResult.succ();
                }
            }
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.DELETE_DEPARTMENT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.DELETE_DEPARTMENT_IS_ERROR);
        }
    }

    /**
     * @param departmentIdsDto 部门id数组字符串实体
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 部门批量删除
     * @author maodi
     * @createDate 2018/11/13 17:49
     */
    @DeleteMapping
    public ApiResult<NullObject> deleteDepartmentMulti(@RequestBody DepartmentIdsDto departmentIdsDto) {
        try {
            String departmentIdsStr = departmentIdsDto.getDepartmentIds();
            if (StringUtils.isBlank(departmentIdsStr)) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_IDS_IS_NOT_NULL);
            }
            String[] departmentIds = departmentIdsStr.split(",");
            if (departmentIds == null || departmentIds.length < 1) {
                return ApiResult.fail(OrganizationErrorCode.DEPARTMENT_IDS_IS_NOT_NULL);
            }
            departmentService.deleteDepartmentMulti(departmentIds);
            for (String deparmentId : departmentIds) {
                ApiResult<NullObject> result = authService.initDepartmentPermission(deparmentId, "clear");
                if (!result.isSucc()) {
                    throw new RuntimeException(result.getMessage());
                }
            }
            return ApiResult.succ();
        } catch (Exception e) {
            LOGGER.error(OrganizationErrorCode.DELETE_DEPARTMENT_MULTI_IS_ERROR.getMessage(), e);
            return ApiResult.fail(OrganizationErrorCode.DELETE_DEPARTMENT_MULTI_IS_ERROR);
        }
    }

    /**
     * @param list 部门列表
     * @param page 页数
     * @param size 每页数量
     * @return void
     * @description 为部门列表添加序号
     * @author maodi
     * @createDate 2018/11/8 10:30
     */
    private void addNum(List<DepartmentDto> list, int page, int size) {
        int start = (page - 1) * size + 1;
        for (DepartmentDto departmentDto : list) {
            departmentDto.setNum(start++);
        }
    }

}
